/*
 ** $Id: lua.c,v 1.160.1.2 2007/12/28 15:32:23 roberto Exp $
 ** Lua stand-alone interpreter
 ** See Copyright Notice in lua.h
 */

#include "luaEngine.h"
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define lua_c

#include "lauxlib.h"
#include "lualib.h"

#include "ltable.h"

#include "luaCommonlib.h"

#define BUFFERLEN 300

static lua_State *globalL = NULL;



static int docall (lua_State *L, int narg, int clear) {
    int status;
    status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), 0);
    if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
    return status;
}



void releaseNode(HPNode * node)
{
	if (node != NULL)
    {
		if (node->value != NULL)
        {
			releaseHPData(node->value);
        }
		node->value = NULL;
		if (node->key != NULL)
        {
			free(node->key);
        }
		node->next=NULL;
		//free(node->next);
    }
    free(node);
    node=NULL;
}

void releaseHPTable(HPTable* hptable){
	if(hptable!=NULL){
		HPNode * temp=hptable->fielddatas;
		while(temp!=NULL){
			HPNode * next=temp->next;
			releaseNode(temp);
			temp=next;
		}
		//释放数组部分
		if(hptable->arraydatas!=NULL){
			releaseHPDatas(hptable->arraydatas,hptable->arraylenght);
			hptable->arraydatas=NULL;
			hptable->arraylenght=0;
		}
		free(hptable);
	}
}


/*************************不可外部访问的函数*****************************/

HPData* CopyTable(const HPData* scrtable){
	HPData* r=NULL;
	int i=0;
	if(scrtable!=NULL && scrtable->type==LUA_TTABLE && scrtable->datat!=NULL){
		HPNode * temp=scrtable->datat->fielddatas;
		r = CreateTABLEHPData();
		//拷贝key-value部分
		while(temp!=NULL){
			HPData * td=CopyHPData(temp->value);
			TableRawSet(r, temp->key, td);
			temp=temp->next;
		}
		//拷贝数组部分
		if(scrtable->datat->arraydatas!=NULL && scrtable->datat->arraylenght>0){
			HPData** array=CreateHPDataArray(scrtable->datat->arraylenght);
			HPData** scrarray=scrtable->datat->arraydatas;
			for(i=0;i<scrtable->datat->arraylenght;i++){
				array[i]=CopyHPData(scrarray[i]);
			}
			TableSetArray(r,array,scrtable->datat->arraylenght);
		}
	}
	return r;
}

//插入table一个key-value
void TableSet(HPTable* table, const char * key,HPData * data){
	if( table!=NULL && key!=NULL){
		HPNode * tempnode=table->fielddatas;
		HPNode * prenode=NULL;
		//删除原有数据
		while (tempnode != NULL)
        {
			if (strcmp(tempnode->key, key) == 0)
            {
                HPNode * deleteNode=tempnode;
                if (prenode!=NULL) {
                    prenode->next = tempnode->next;
                    tempnode=prenode->next;
                }else {
                    table->fielddatas=tempnode->next;
                    tempnode=NULL;
                    if (table->fielddatas!=NULL) {
                        tempnode=table->fielddatas->next;
                    }
                }
                releaseNode(deleteNode);
            }
			else
            {
				prenode = tempnode;
				tempnode = tempnode->next;
            }
        }
		
		
		tempnode=NULL;
		if(data!=NULL){
            HPNode * tempnode = (HPNode *) malloc(sizeof(HPNode));
            tempnode->key=(char *) malloc(sizeof(char)*(strlen(key)+1));
            strcpy(tempnode->key,key);
            tempnode->value=data;
            tempnode->next=table->fielddatas;
            table->fielddatas=tempnode;//将新数据插入链表头
		}
	}
}
//根据key值获取table的value
const HPData * TableGet(HPTable* table, const char * key)
{
	if (table != NULL && key!=NULL)
    {
		HPNode * tempnode = table->fielddatas;
		while (tempnode != NULL)
        {
			const char * tempkey = tempnode->key;
			if (tempkey!=NULL && strcmp(tempkey,key)==0)
            {
				//匹配
				return tempnode->value;
            }
			tempnode=tempnode->next;
        }
    }
	return NULL;
}

void TableSetArrayT(HPTable* table, HPData ** datas, int lenght)
{
	if (table != NULL)
    {
		//清除原有的数组
		if (table->arraydatas != NULL && table->arraylenght > 0)
        {
			releaseHPDatas(table->arraydatas, table->arraylenght);
			table->arraylenght = 0;
			table->arraydatas = NULL;
        }
		if (datas != NULL && lenght > 0)
        {
			table->arraylenght = lenght;
			table->arraydatas = datas;
        }
    }
}


//获取各种HPData
static HPData * CreateHPData(){
	HPData * hd=(HPData *)malloc(sizeof(HPData));
	hd->type=LUA_TNONE;
	hd->datab=0;
	hd->datad=0;
	hd->dataf=NULL;
	hd->datas=NULL;
	hd->datat=NULL;
	hd->datau=NULL;
	return hd;
}


//将table加入栈顶
static int PushHPTable(lua_State *L,HPTable* hptable){
	int i,do_ok=0;
	if(hptable!=NULL){
		HPNode * temnode=hptable->fielddatas;
		HPData ** datas=hptable->arraydatas;
		int arraylenght=hptable->arraylenght;
		
		lua_newtable(L);
        
		//设置key-value部分
		while(temnode!=NULL){
			lua_pushstring(L, temnode->key);
			if(!PushHPData(L,temnode->value)){
				return do_ok;
			}
			lua_rawset(L, -3);
			temnode=temnode->next;
		}
		
		//设置数组部分
		if (arraylenght > 0 && datas != NULL)
        {
			for (i = 0; i < arraylenght; i++)
            {
				PushHPData(L, datas[i]);
				lua_rawseti(L, -2, i+1);
            }
        }
		do_ok=1;
	}
	return do_ok;
}


//获取栈顶table并转换为hptable返回
static HPTable* getHPTable(lua_State *L)
{
	int tarrayindex = 0;
	int tlenth;
	int nIndex;
    
	//遍历table，包括key-value和数组两种情况
	if (lua_istable(L, -1))
    {
		HPData ** arraydatas=NULL;
		//生成一个hptable
		HPTable* hptable = (HPTable *) malloc(sizeof(HPTable));
		hptable->arraylenght=0;
		hptable->arraydatas=NULL;
		hptable->fielddatas=NULL;
		
		//得到table的数组长度
		tlenth = luaL_getn(L, -1);
		if(tlenth>0){
			hptable->arraylenght = tlenth;
			arraydatas = (HPData **) malloc(sizeof(HPData*) * tlenth);
			hptable->arraydatas=arraydatas;
		}
        
		//遍历table元素
		nIndex = lua_gettop(L); // 取 table 索引值
		lua_pushnil(L); // nil 入栈作为初始 key
		while (0 != lua_next(L, nIndex))
        {
			// 现在栈顶（-1）是 value，-2 位置是对应的 key
			// 这里可以判断 key 是什么并且对 value 进行各种处理
            
			if (lua_isnumber(L, -2))
            {//是数组元素
				if (tarrayindex < tlenth)
                {
					HPData * tempdata = getHPData(L);
					int keyindex=(int)lua_tonumber(L, -2)-1;
					if (tempdata == NULL)
                    {
						releaseHPTable(hptable);
						return NULL;//错误返回
                    }
                    if (keyindex>=tlenth) {
                        releaseHPTable(hptable);
                        releaseHPData(tempdata);
                        return NULL;//错误返回
                    }
                    if (arraydatas != NULL) {
                        arraydatas[keyindex] = tempdata;
                    }
					tarrayindex++;
                }
				else
                {
					releaseHPTable(hptable);
					return NULL;//错误返回
                }
            }
			else if (lua_isstring(L, -2))
            {//是key-value形式
				const char *pd;
				//先获取value;
				HPData * valuedata = getHPData(L);
				if (valuedata == NULL)
                {
					releaseHPTable(hptable);
					return NULL;//错误返回
                }
                
				//获取key
				pd = lua_tostring(L, -2);
				TableSet(hptable, pd,valuedata);
            }
			lua_pop( L, 1 ); // 弹出 valuse，让 key 留在栈顶
        }
		// 现在栈顶是 table
		return hptable;
    }
	return NULL;
}



/*************************开放的函数*****************************/
//将hpdata压入栈顶
int PushHPData(lua_State *L,const HPData * hpdata){
	int do_ok=0;
	if(hpdata!=NULL){
		if(hpdata->type==LUA_TNUMBER){
			lua_pushnumber(L, hpdata->datad);
			do_ok=1;
		}
		else if(hpdata->type==LUA_TSTRING && hpdata->datas!=NULL){
			lua_pushstring(L, hpdata->datas);
			do_ok=1;
		}
		else if(hpdata->type==LUA_TBOOLEAN){
			if(hpdata->datab){
				lua_pushboolean(L,1);
			}else{
				lua_pushboolean(L,0);
			}
			do_ok=1;
		}
		else if(hpdata->type==LUA_TTABLE && hpdata->datat!=NULL){
			PushHPTable(L,hpdata->datat);
			do_ok=1;
		}
		else if(hpdata->type==LUA_TFUNCTION && hpdata->dataf!=NULL){
			lua_rawgeti(L, LUA_REGISTRYINDEX, hpdata->dataf->func);//依然把该函数留在栈顶
			do_ok=1;
		}
		else if(hpdata->type==LUA_TUSERDATA && hpdata->datau!=NULL){
			lua_pushlightuserdata(L,hpdata->datau);
			do_ok=1;
		}
		else if(hpdata->type==LUA_TNIL){
			lua_pushnil(L);
			do_ok=1;
		}
	}
	return do_ok;
}

//获取栈顶元素并转换为HPData返回
HPData * getHPData(lua_State *L){
	HPData * hd=CreateHPData();
	if(lua_type(L,-1)==LUA_TNUMBER){//数字类型
		hd->type=LUA_TNUMBER;
		hd->datad=lua_tonumber(L, -1);
	}else if(lua_type(L,-1)==LUA_TSTRING){//字符串类型
		const char * temp=lua_tostring(L, -1);
		hd->type=LUA_TSTRING;
		hd->datas=(char *) malloc(sizeof(char)*(strlen(temp)+1));
		//产生copy
		strcpy(hd->datas,temp);
	}else if(lua_isboolean(L,-1)){//布尔型
		hd->type=LUA_TBOOLEAN;
		hd->datab=lua_toboolean(L, -1);
	}
	else if(lua_istable(L, -1)){//table型
		hd->type=LUA_TTABLE;
		hd->datat=getHPTable(L);
	}
	else if(lua_isfunction(L,-1)){//函数类型
		HPFunction * copyone=(HPFunction *) malloc(sizeof(HPFunction));
		hd->type=LUA_TFUNCTION;
		copyone->func = luaL_ref(L, LUA_REGISTRYINDEX);
		copyone->count=1;
		hd->dataf = copyone;
		lua_rawgeti(L, LUA_REGISTRYINDEX, copyone->func);//依然把该函数留在栈顶
	}
	else if(lua_islightuserdata(L,-1)){//自定义类型
		hd->type=LUA_TUSERDATA;
		hd->datau=lua_touserdata(L,-1);
	}
	else if(lua_isnil(L,-1)){
		hd->type=LUA_TNIL;
	}
	if(hd->type==LUA_TNONE){//没有获得数据
		releaseHPData(hd);
		return NULL;
	}else{
		return hd;
	}
    
}

char * appendstr(const char * source1,char buffer[BUFFERLEN],const char * source2,const char * source3){
	char * result=NULL;
	int i,tempi;
	int sourcelen1=0,sourcelen2=0,sourcelen3=0,bufferlen=0;
	
	if (source1!=NULL) {
		sourcelen1=strlen(source1);
	}
	if (source2!=NULL) {
		sourcelen2=strlen(source2);
	}
	if (source3!=NULL) {
		sourcelen3=strlen(source3);
	}
	if (buffer!=NULL) {
		bufferlen=strlen(buffer);
	}
	tempi=(sourcelen1+sourcelen2+sourcelen3+bufferlen+1);
	result=(char *)malloc(sizeof(char)* tempi);
	for (i=0; i<tempi; i++) {
		result[i]=0;
	}
	if (source1!=NULL) {
		strcat(result, source1);
	}
	if (buffer!=NULL && bufferlen>0) {
		strcat(result, buffer);
		buffer[0]='\0';
	}
	if (source2!=NULL) {
		strcat(result, source2);
	}
	if (source3!=NULL) {
		strcat(result, source3);
	}
	if (buffer!=NULL) {
		buffer[0]='\0';
	}
	return result;
}

char * TableToString(const HPTable * hptable)
{
	char * rd = NULL, * temp=NULL;
	int i=0;
	if (hptable != NULL)
	{
		char buffer[BUFFERLEN];
		
		HPNode * temnode = hptable->fielddatas;
		HPData ** datas = hptable->arraydatas;
		int arraylenght = hptable->arraylenght;
		buffer[0]='\0';
		
		strcat(buffer, "{");
		//设置key-value部分
		while (temnode != NULL)
		{
			char * vd = HPDataToString(temnode->value, temnode->key);
			if (vd != NULL)
			{
				int strll=strlen(buffer)+strlen(vd)+1;
                
				if (strll>(BUFFERLEN-1)) {
					temp=rd;
					rd=appendstr(rd,buffer,vd,",");
					if (temp!=NULL) {
						free(temp);
					}
					temp=NULL;
				}else {
					strcat(buffer, vd);
					strcat(buffer, ",");
				}
				free(vd);
			}
			temnode = temnode->next;
		}
		
		//设置数组部分
		if (arraylenght > 0 && datas != NULL)
		{
			for (i = 0; i < arraylenght; i++)
			{
				char * vd = HPDataToString(datas[i], NULL);
				if (vd != NULL)
				{
					int strll=strlen(buffer)+strlen(vd)+1;
					if (strll>(BUFFERLEN-1)) {
						temp=rd;
						rd=appendstr(rd,buffer,vd,",");
						if (temp!=NULL) {
							free(temp);
						}
						temp=NULL;
					}else {
						strcat(buffer, vd);
						strcat(buffer, ",");
					}
					free(vd);
				}
			}
		}
		temp=rd;
		rd=appendstr(rd,buffer,"}",NULL);
		if (temp!=NULL) {
			free(temp);
		}
		temp=NULL;
	}
	return rd;
}

char * HPDataToString(const HPData * hpdata,const char * Key){
	char buffer[BUFFERLEN];
	char * rd=NULL;
	if(hpdata==NULL){
		return NULL;
	}
	buffer[0]='\0';
	if(Key!=NULL){
		strcat(buffer,Key);
		strcat(buffer,"=");
	}
	
	if(hpdata->type==LUA_TNUMBER){
		char caCond[20];
		sprintf(caCond, "%.2f", hpdata->datad);
		strcat(buffer,caCond);
	}
	else if(hpdata->type==LUA_TSTRING && hpdata->datas!=NULL){
		int i,slen=strlen(hpdata->datas)+1+2+strlen(buffer);
		rd=(char *)malloc(sizeof(char)*slen);
		for (i=0; i<slen; i++) {
			rd[i]=0;
		}
		strcat(rd,buffer);
		strcat(rd,"\"");
		strcat(rd,hpdata->datas);
		strcat(rd,"\"");
		return rd;
	}
	else if(hpdata->type==LUA_TBOOLEAN){
		if(hpdata->datab==1){
			strcat(buffer,"true");
		}else{
			strcat(buffer,"false");
		}
	}
	else if(hpdata->type==LUA_TTABLE && hpdata->datat!=NULL){
		char * tabd=TableToString(hpdata->datat);
		int i,slen=strlen(tabd)+1+strlen(buffer);
		rd=(char *)malloc(sizeof(char)*slen);
		for (i=0; i<slen; i++) {
			rd[i]=0;
		}
		strcat(rd,buffer);
		strcat(rd,tabd);
		free(tabd);
		return rd;
	}
	else if(hpdata->type==LUA_TFUNCTION && hpdata->dataf!=NULL){
		strcat(buffer,"nil");
	}
	else if(hpdata->type==LUA_TUSERDATA && hpdata->datau!=NULL){
		strcat(buffer,"nil");
	}
	else if(hpdata->type==LUA_TNIL){
		strcat(buffer,"nil");;
	}
	else{
		return NULL;
	}
	rd = (char *) malloc(strlen(buffer)+1);
	strcpy(rd,buffer);
	return rd;
}



HPData * CreateHPDataFromString(const char * tabledata,const char * dataname,int charnum){
	HPData * temp=NULL;
	
	lua_State *tempState = lua_open();
	
	lua_State * LL=lua_newthread(tempState);
    
	int status=luaL_loadbuffer(LL, tabledata,charnum, "getdata")||lua_resume(LL, 0);
	printf("%s%d\n","CreateHPDataFromString:",status);
	if (status==0) {
		lua_getglobal(LL,dataname);
		temp=getHPData(LL);
	}
	lua_close(tempState);
	tempState=NULL;
	return temp;
	
	/*int status=luaL_loadbuffer(tempState, tabledata, strlen(tabledata), "getdata")
     || docall(tempState, 0, 1);
     
     printf("%s%d\n","CreateHPDataFromString:",status);
     
     if(status==0){
     lua_getglobal(tempState,dataname);
     temp=getHPData(tempState);
     lua_pushnil(tempState);
     lua_setglobal(tempState, dataname);
     }
     lua_settop(tempState,0);
     lua_close(tempState);
     tempState=NULL;
     return temp;*/
}

int HPdofile (const char *name) {
	int result=1;
	lua_State * LL=lua_newthread(globalL);
	int llindex=luaL_ref(globalL, LUA_REGISTRYINDEX);
	result=(luaL_loadfile(LL, name) || docall(LL, 0, 1));
	luaL_unref(globalL, LUA_REGISTRYINDEX,llindex);
	return result;
}


int HPdobuffer (const char *s, const char *name,int datanum) {
	int result=1;
	lua_State * LL=lua_newthread(globalL);
	int llindex=luaL_ref(globalL, LUA_REGISTRYINDEX);
	result=(luaL_loadbuffer(LL, s, datanum, name)||lua_resume(LL, 0));
	luaL_unref(globalL, LUA_REGISTRYINDEX,llindex);
	return result;
}


//执行function,args参数列表，参数个数，返回值个数
int DoFunctione(const HPData * func,HPData ** paramdatas,int paramNum,HPData ** resultdatas,int resultNum){
	int result=1;
	int argn=paramNum;
	if(globalL!=NULL && func!=NULL && func->type==LUA_TFUNCTION){
		lua_State * TL=lua_newthread(globalL);
		int Tlindex=luaL_ref(globalL, LUA_REGISTRYINDEX);
		int i;
	    lua_rawgeti(TL, LUA_REGISTRYINDEX, func->dataf->func);
	    if(argn>0 && paramdatas!=NULL){
			for(i=0;i<argn;i++){
				const HPData * tmp=paramdatas[i];
				PushHPData(TL,tmp);
			}
	    }
	    result=lua_resume(TL, argn);
	    if(result==0 && resultNum>0 && resultdatas!=NULL){
			for(i=0;i<resultNum;i++){
				resultdatas[i]=getHPData(TL);
				lua_pop(TL, 1);
			}
	    }
		luaL_unref(globalL, LUA_REGISTRYINDEX,Tlindex);
	}
	return result;
}

//int DoLuaFunctione(const char * funcName, const HPData* data){
int DoLuaFunctione(const char * funcName, HPData ** paramdatas,int paramNum){
    if(!globalL){
        return 0;
    }

    lua_getglobal(globalL, funcName);
    for (int i = 0; i < paramNum; i++) {
        PushHPData(globalL, paramdatas[i]);
    }
    //PushHPData(globalL, data);
    int ret = lua_pcall(globalL, paramNum, 1, 0);
    if (ret) {
        printf("lua_pcall failer:%s", funcName);
    }
    lua_pop(globalL, 1);
    return ret;
}

void  ReleaseEnvironment()
{
	if(globalL!=NULL)
    {
		lua_close(globalL);
		globalL=NULL;
    }
}
void  InitEnvironment()
{
	globalL = lua_open(); //create state
	lua_gc(globalL, LUA_GCSTOP, 0); /* stop collector during initialization */
	luaL_openlibs(globalL); /* open libraries */
	lua_gc(globalL, LUA_GCRESTART, 0);
}

void AddCustomLib(luaL_Reg* reg)
{
    lua_gc(globalL, LUA_GCSTOP, 0); /* stop collector during initialization */
	luaL_addlib(globalL, reg); /* open libraries */
	lua_gc(globalL, LUA_GCRESTART, 0);
}

void setGloble(const HPData * data,char * fieldname){
	if(globalL!=NULL && data!=NULL && data->type!=LUA_TNONE){
		lua_State * LL=lua_newthread(globalL);
		int llindex=luaL_ref(globalL, LUA_REGISTRYINDEX);
		PushHPData(LL,data);
		lua_setglobal(LL, fieldname);
		luaL_unref(globalL, LUA_REGISTRYINDEX,llindex);
	}
	if (globalL!=NULL && data==NULL) {
		lua_State * LL=lua_newthread(globalL);
		int llindex=luaL_ref(globalL, LUA_REGISTRYINDEX);
		lua_pushnil(LL);
		lua_setglobal(LL, fieldname);
		luaL_unref(globalL, LUA_REGISTRYINDEX,llindex);
	}
}
HPData * getGloble(const char * fieldname){
	HPData * temp=NULL;
	if(globalL!=NULL){
		lua_State * LL=lua_newthread(globalL);
		int llindex=luaL_ref(globalL, LUA_REGISTRYINDEX);
		lua_getglobal(LL,fieldname);
		temp=getHPData(LL);
		lua_pop(LL, 1); //将table从栈中弹出
		luaL_unref(globalL, LUA_REGISTRYINDEX,llindex);
	}
	return temp;
}

const HPData * TableGetArrayIn(const HPData* table,int index){
	const HPData * result=NULL;
	if(table!=NULL && table->datat!=NULL && table->datat->arraydatas!=NULL && index<table->datat->arraylenght){
		result=table->datat->arraydatas[index];
	}
	return result;
}
int TableGetLength(const HPData* table){
	if(table!=NULL && table->datat!=NULL){
		return table->datat->arraylenght;
	}
	return 0;
}

void TableSetArray(HPData* table, HPData ** datas, int lenght)
{
	//若已有array部分则删除
	if (datas != NULL && table != NULL && table->type == LUA_TTABLE
        && table->datat != NULL && lenght > 0)
    {
		TableSetArrayT(table->datat, datas, lenght);
    }
}

//插入table一个key-value
void TableRawSet(HPData* table, const char * key,HPData * data){
	if(data!=NULL && table!=NULL && table->type==LUA_TTABLE && table->datat!=NULL && key!=NULL){
		TableSet(table->datat, key,data);
	}
}

//根据key值获取table的value
const HPData * TableRawGet(const HPData* table, const char * key)
{
	if (table != NULL && table->type == LUA_TTABLE && table->datat != NULL
        && key != NULL)
    {
		return TableGet(table->datat, key);
    }
	return NULL;
}


HPData * CreateNUMHPData(double number){
	HPData * hd=CreateHPData();
	hd->type=LUA_TNUMBER;
	hd->datad=number;
	return hd;
}
HPData * CreateSHPData(const char * s){
	//产生copy
	HPData * hd=CreateHPData();
	hd->type=LUA_TSTRING;
	hd->datas=(char *) malloc(sizeof(char)*(strlen(s)+1));
	strcpy(hd->datas,s);
	return hd;
}
HPData * CreateBOOLHPData(int booli){
	HPData * hd=CreateHPData();
	hd->type=LUA_TBOOLEAN;
	if(booli==0){
		hd->datab=0;
	}else{
		hd->datab=1;
	}
	return hd;
}

HPData * CreateTABLEHPData(){//生成一个空table
	HPData * hd=CreateHPData();
	hd->type=LUA_TTABLE;
	hd->datat=(HPTable *) malloc(sizeof(HPTable));
	hd->datat->arraydatas=NULL;
	hd->datat->arraylenght=0;
	hd->datat->fielddatas=NULL;
	return hd;
}
HPData * CreateNILHPData(){
	HPData * hd=CreateHPData();
	hd->type=LUA_TNIL;
	return hd;
}

HPData ** CreateHPDataArray(int length){
	HPData ** array=NULL;
	array=(HPData **) malloc(sizeof(HPData*)*length);
	return array;
}

HPData * CopyHPData(const HPData * scrhpdata)
{
	HPData * r = NULL;
	if (scrhpdata != NULL)
    {
		switch (scrhpdata->type)
        {
			case LUA_TNUMBER:
				r = CreateNUMHPData(scrhpdata->datad);
				break;
			case LUA_TSTRING:
				r = CreateSHPData(scrhpdata->datas);
				break;
			case LUA_TBOOLEAN:
				r = CreateBOOLHPData(scrhpdata->datab);
				break;
			case LUA_TTABLE:
				r = CopyTable(scrhpdata);
				break;
			case LUA_TFUNCTION:
				if (scrhpdata->dataf != NULL
                    && scrhpdata->dataf->func != LUA_REFNIL)
                {
					r = CreateHPData();
					r->type = LUA_TFUNCTION;
					scrhpdata->dataf->count++;
					r->dataf=scrhpdata->dataf;
                }
				break;
			case LUA_TNIL:
				r = CreateNILHPData();
				break;
        }
    }
	return r;
}

void releaseHPDatas(HPData ** hpdatas, int length)
{
	if (hpdatas != NULL)
    {
		int i = 0;
		for (i = 0; i < length; i++)
        {
            if (hpdatas[i]!=NULL) {
                releaseHPData(hpdatas[i]);
            }
        }
		free(hpdatas);
    }
}

void releaseHPData(HPData * hpdata)
{
	if (hpdata != NULL)
    {
		switch (hpdata->type)
        {
			case LUA_TNUMBER:
				break;
			case LUA_TSTRING:
				if (hpdata->datas != NULL)
                {
					free(hpdata->datas);
					hpdata->datas = NULL;
                }
				break;
			case LUA_TBOOLEAN:
				break;
			case LUA_TTABLE:
				if (hpdata->datat != NULL)
                {
					releaseHPTable(hpdata->datat);
                }
				hpdata->datat = NULL;
				break;
			case LUA_TFUNCTION:
				if (hpdata->dataf != NULL)
                {
                    hpdata->dataf->count=hpdata->dataf->count-1;
                    if (hpdata->dataf->count==0 && globalL != NULL) {
                        if (hpdata->dataf->func != LUA_REFNIL)
                        {
                            luaL_unref(globalL, LUA_REGISTRYINDEX,
                                       hpdata->dataf->func);
                            
                            hpdata->dataf->func=LUA_REFNIL;
                        }
                        free(hpdata->dataf);
                    }
                    hpdata->dataf = NULL;
                }
				break;
			case LUA_TUSERDATA:
				hpdata->datau = NULL;
				break;
			case LUA_TNIL:
				break;
        }
		free(hpdata);
    }
}

void LuaPrint(const char * s){
	printf("%s",s);
}

//test
/*int testluado(const char * data,int numdata){
 int i;
 
 HPData * temptable=NULL;
 HPData * func=NULL;
 
 
 HPData ** args=NULL;
 HPData ** tablers=NULL;
 const HPData * tempdata=NULL;
 HPData * tempdata1=NULL;
 
 //__UHEAP_MARK;
 
 //初始化环境
 //InitEnvironment();
 
 //设置全局变量
 tempdata1=CreateSHPData("12345678o");
 setGloble(tempdata1,"test123");
 releaseHPData(tempdata1);
 tempdata1=NULL;
 
 //设置一个table的全局变量
 temptable=CreateTABLEHPData();
 //key-value
 tempdata1=CreateSHPData("globlename111");
 TableRawSet(temptable,"name",tempdata1);
 //数组
 tablers=CreateHPDataArray(2);
 tablers[0]=CreateNUMHPData(12);
 tablers[1]=CreateSHPData("globleindex2");
 TableSetArray(temptable,tablers,2);
 setGloble(temptable,"globle");
 //释放资源,table中的资源由table释放
 releaseHPData(temptable);
 temptable=NULL;
 
 //导入执行lua脚本
 luaL_loadbuffer(globalL, data, numdata, "test")||lua_resume(globalL, 0);
 
 
 //获取全局变量screeen
 temptable=getGloble("screen");
 tempdata=TableRawGet(temptable,"id");
 if (tempdata->type == LUA_TSTRING)
 {
 char caCond[100];
 sprintf(caCond, "%s\n", tempdata->datas);
 LuaPrint(caCond);
 }
 
 //获取全局变量tabletest
 temptable=getGloble("tabletest");
 if(temptable!=NULL && temptable->type==LUA_TTABLE && temptable->datat!=NULL){
 //得到a field
 int length=0;
 tempdata= TableRawGet(temptable, "a");
 if(tempdata!=NULL && tempdata->type==LUA_TNUMBER){
 char caCond[100];
 sprintf(caCond, "tabletest 'a' :%f \n",tempdata->datad);
 LuaPrint(caCond);
 }
 //b field是一个lua函数，若要存储该函数，则需要copy，table释放则该资源也释放
 func= CopyHPData(TableRawGet(temptable, "b"));
 
 //得到数组，并获得数组变量
 length= TableGetLength(temptable);
 for(i=0;i<length;i++){
 tempdata=TableGetArrayIn(temptable,i);
 if(tempdata!=NULL && tempdata->type==LUA_TNUMBER){
 char caCond[100];
 sprintf(caCond, "tabletest array [%d] :%f \n",i,tempdata->datad);
 LuaPrint(caCond);
 }				  
 }
 }
 //释放资源,table中的资源由table释放
 releaseHPData(temptable);
 temptable=NULL;
 
 //将tabletest全局变量置空
 tempdata1=CreateNILHPData();
 setGloble(tempdata1,"tabletest");
 releaseHPData(tempdata1);
 tempdata1=NULL;
 
 //执行函数
 if(func!=NULL){
 //共两个参数
 args=CreateHPDataArray(2);
 //第一个参数
 args[0]=CreateNUMHPData(78);
 //第二个参数是table，包含两项
 args[1]=CreateTABLEHPData();
 tablers=CreateHPDataArray(2);
 tablers[0]=CreateNUMHPData(12);
 tablers[1]=CreateSHPData("hehe");
 TableSetArray(args[1],tablers,2);
 DoFunctione(func,args,2,1);
 }
 
 //释放环境
 //ReleaseEnvironment();
 //__UHEAP_MARKEND;
 return 1;
 }*/
